package com.sen.common.widget;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;

import com.sen.common.widget.form.Content;

/**
 * 所有HTML基础组件的父类.
 * 
 * @author sen
 */
public class Component implements ToHtmlable {

	private String tagName;
	private Attribute attribute;
	private List<Component> children = new LinkedList<Component>();

	public Component(String tagName) {
		this.tagName = tagName;
	}

	public String toHtml() {
		StringBuffer html = new StringBuffer("<");
		html.append(tagName).append(specialAttributes()).append(
				attribute == null ? "" : attribute.toHtml()).append(">")
				.append(componentsHtmlIfNonEmpty()).append("</")
				.append(tagName).append(">");
		return html.toString();
	}

	private String componentsHtmlIfNonEmpty() {
		if (CollectionUtils.isEmpty(children)) {
			return StringUtils.EMPTY;
		}
		StringBuffer html = new StringBuffer();
		for (Component child : children) {
			html.append(child.toHtml());
		}
		return html.toString();
	}

	protected List<Component> getChildren() {
		return children;
	}

	public Component clearChildren() {
		children.clear();
		return this;
	}

	// ---------------内嵌控件-------------------
	public Component add(Component child) {
		if (null == child) {
			return this;
		}
		children.add(child);
		return this;
	}

	public Component add(String content) {
		if (null == content) {
			return this;
		}
		children.add(new Content(content));
		return this;
	}

	// -------------基本属性-------------------------
	public Component attr(Attribute attribute) {
		this.attribute = Attributes.merge(attribute, this.attribute);
		return this;
	}

	public Component id(String id) {
		if (StringUtils.isEmpty(id)) {
			return this;
		}
		this.attribute = Attributes.merge(new Attribute().id(id),
				this.attribute);
		return this;
	}

	public Component name(String name) {
		if (StringUtils.isEmpty(name)) {
			return this;
		}
		this.attribute = Attributes.merge(new Attribute().name(name),
				this.attribute);
		return this;
	}

	public Component className(String className) {
		if (StringUtils.isEmpty(className)) {
			return this;
		}
		this.attribute = Attributes.merge(new Attribute().className(className),
				this.attribute);
		return this;
	}

	public Component height(String height) {
		if (StringUtils.isEmpty(height)) {
			return this;
		}
		this.attribute = Attributes.merge(new Attribute().height(height),
				this.attribute);
		return this;
	}

	public Component width(String width) {
		if (StringUtils.isEmpty(width)) {
			return this;
		}
		this.attribute = Attributes.merge(new Attribute().width(width),
				this.attribute);
		return this;
	}

	public Component title(String title) {
		if (StringUtils.isEmpty(title)) {
			return this;
		}
		this.attribute = Attributes.merge(new Attribute().title(title),
				this.attribute);
		return this;
	}

	public Component caption(String caption) {
		if (StringUtils.isEmpty(caption)) {
			return this;
		}
		this.attribute = Attributes.merge(new Attribute().caption(caption),
				this.attribute);
		return this;
	}

	public Component style(String style) {
		this.attribute = Attributes.merge(new Attribute().style(style), this.attribute);
		return this;
	}

	public Component style(String styleName, String styleValue,
			String... others) {
		this.attribute = Attributes.merge(new Attribute().style(styleName,
				styleValue, others), this.attribute);
		return this;
	}

	public Component style(final Map<String, String> styles) {
		this.attribute = Attributes.merge(new Attribute().style(styles),
				this.attribute);
		return this;
	}

	/**
	 * 其它控件的特殊属性. <code>Component</code>类的该方法返回空字符!
	 */
	protected String specialAttributes() {
		return StringUtils.EMPTY;
	}

	// -----------事件--------------------
	public Component click(String functions) {
		return bind(Events.CLICK, functions);
	}

	public Component dblclick(String functions) {
		return bind(Events.DBLCLICK, functions);
	}

	public Component change(String functions) {
		return bind(Events.CHANGE, functions);
	}
	
	public Component propertyChange(String functions) {
		return bind(Events.PROPERTYCHANGE, functions);
	}

	public Component keyup(String functions) {
		return bind(Events.KEYUP, functions);
	}

	public Component keypress(String functions) {
		return bind(Events.KEYPRESS, functions);
	}

	public Component keydown(String functions) {
		return bind(Events.KEYDOWN, functions);
	}

	public Component mouseup(String functions) {
		return bind(Events.MOUSEUP, functions);
	}

	public Component mouseover(String functions) {
		return bind(Events.MOUSEOVER, functions);
	}

	public Component mouseout(String functions) {
		return bind(Events.MOUSEOUT, functions);
	}

	public Component mousemove(String functions) {
		return bind(Events.MOUSEMOVE, functions);
	}

	public Component mousedown(String functions) {
		return bind(Events.MOUSEDOWN, functions);
	}

	public Component focus(String functions) {
		return bind(Events.FOCUS, functions);
	}

	public Component blur(String functions) {
		return bind(Events.BLUR, functions);
	}

	private Component bind(Events event, String functions) {
		this.attr(event.event(functions));
		return this;
	}
}
